/*
 * parola.h
 *
 * Copyright (C) 2011, 2012 - Massimiliano Maniscalco
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _PAROLA_H_
#define _PAROLA_H_
#define TOTALE_TIPI		10

#include "voce.h"

using namespace std;

class Parola: public Voce
{
	
public:
	Parola() :
		_kotoba ( "" ), _yomikata ( "" ), _gaikokugo ( "" ), _tipo ( 0 )
{ }
	inline Parola ( const Parola &verbum );
	inline ~Parola();
	inline Parola& operator=( const Parola &verbum );
	inline bool operator<( const Parola &verbum ) const;
	inline bool operator==( const Parola &verbum ) const;
	inline void set_kotoba ( const Glib::ustring &str ) { _kotoba.assign ( str ); }
	inline void set_kotoba ( const char *cstr );
	inline Glib::ustring get_kotoba ( void ) const { return _kotoba; }
	inline void set_yomikata ( const Glib::ustring &str ) { _yomikata.assign ( str ); }
	inline void set_yomikata ( const char *cstr );
	inline Glib::ustring get_yomikata ( void ) const { return _yomikata; }
	inline void set_gaikokugo ( const Glib::ustring &str ) { _gaikokugo.assign ( str ); }
	inline void set_gaikokugo ( const char *cstr );
	inline Glib::ustring get_gaikokugo ( void ) const { return _gaikokugo; }
	inline void set_tipo ( char val ) { _tipo = val; }
	inline void set_tipo ( const char *cstr ) { _tipo = atoi ( cstr ); }
	void set_tipo_from_name ( const Glib::ustring &str );
	static char get_tipo_index_from_name ( const Glib::ustring &str );
	inline char get_tipo ( void ) const { return _tipo; }
	Glib::ustring get_tipo_name ( void ) const;
	inline bool has_kanji ( void ) const;
	inline bool is_verbo ( void ) const { return ( _tipo > 3 && _tipo < 9); }
	inline bool is_aggettivo ( void ) const { return ( _tipo > 1 && _tipo < 4 ); }
	inline void cleanup ( void );
	inline Glib::ustring get_xml_string ( const Glib::ustring &language ) const;
	bool get_kanji_list ( list<Glib::ustring> &lista ) const;
	void get_forme_list ( list<Glib::ustring> &lista ) const;
	void get_presente ( Glib::ustring &str, bool _cortese = false, bool _affermativa = true ) const;
	void get_passato ( Glib::ustring &str, bool _cortese = false, bool _affermativa = true ) const;
	void get_sospensivo ( Glib::ustring &str, bool _cortese = false, bool _affermativa = true ) const;
	void get_causale ( Glib::ustring &str ) const;
	void get_avverbiale ( Glib::ustring &str ) const;
	void get_diventare ( Glib::ustring &str, bool _cortese = false, bool _affermativa = true ) const;
	void get_rendere ( Glib::ustring &str, bool _cortese = false, bool _affermativa = true ) const;
	void get_desiderativo ( Glib::ustring &str, bool _affermativa = true );
	void get_volitivo ( Glib::ustring &str, bool _cortese = false, bool _affermativa = true ) const;
	void get_esortativo ( Glib::ustring &str, bool _cortese = false ) const;
	void get_imperativo ( Glib::ustring &str, bool _affermativa = true ) const;
	void get_obbligo ( Glib::ustring &str, bool _cortese = false ) const;
	void get_potenziale ( Glib::ustring &str, bool _cortese = false ) const;
	void get_passivo ( Glib::ustring &str, bool _cortese = false ) const;
	void get_causativo ( Glib::ustring &str, bool _cortese = false ) const;
	void get_condizionale ( Glib::ustring &str ) const;
	void get_verbo_base ( Glib::ustring &str, char index ) const;
	void get_verbo_in_te ( Glib::ustring &str, bool _ta = false ) const;
	
private:
	static const Glib::ustring _godanTable;
	static const Glib::ustring _arrayTipi[TOTALE_TIPI];
	Glib::ustring _kotoba;
	Glib::ustring _yomikata;
	Glib::ustring _gaikokugo;
	char _tipo;
};

inline Parola::
Parola ( const Parola &verbum ) :
	_kotoba ( verbum._kotoba ), _yomikata ( verbum._yomikata ), _gaikokugo ( verbum._gaikokugo ), _tipo ( verbum._tipo )
{
	_contesto = verbum._contesto;
	_valutazione = new char[ _numeroTest ];
	_dataEsame = new time_t[ _numeroTest ];
	char *pv = _valutazione;
	time_t *pt = _dataEsame;
	for ( unsigned short n = 0; n < _numeroTest; n++ )
	{
		*(pv + n) = *(verbum._valutazione + n);
		*(pt + n) = *(verbum._dataEsame + n);
	}
	_testSvolti = verbum._testSvolti;
	_errata = verbum._errata;
}

inline Parola::
~Parola()
{

}

inline Parola& Parola::
operator=( const Parola &verbum )
{
	if ( this != &verbum )
	{
		_kotoba = verbum._kotoba;
		_yomikata = verbum._yomikata;
		_gaikokugo = verbum._gaikokugo;
		_tipo = verbum._tipo;
		_contesto = verbum._contesto;
		char *pv = _valutazione;
		time_t *pt = _dataEsame;
		for ( unsigned short n = 0; n < _numeroTest; n++ )
		{
			*(pv + n) = *(verbum._valutazione + n);
			*(pt + n) = *(verbum._dataEsame + n);
		}
		_testSvolti = verbum._testSvolti;
		_errata = verbum._errata;
	}
	return *this;
}

inline bool Parola::
operator<( const Parola &verbum ) const
{
	if ( _kotoba.raw () < verbum._kotoba.raw () )
		return true;
	if ( ( _kotoba.raw () == verbum._kotoba.raw () ) && ( _yomikata.raw () < verbum._yomikata.raw () ) )
		return true;
	else
		return false;
}

inline bool Parola::
operator==( const Parola &verbum ) const
{
	if ( _kotoba.raw () == verbum._kotoba.raw () )
	{
		if ( _yomikata.raw () == verbum._yomikata.raw () )
		{
			if ( _gaikokugo.raw () == verbum._gaikokugo.raw () )
			{
				if ( _tipo == verbum._tipo )
				{
					return true;
				}
			}
		}
	}
	return false;
}

inline void Parola::
set_kotoba ( const char *cstr )
{
	if ( cstr )
		_kotoba.assign ( cstr );
}

inline void Parola::
set_yomikata ( const char *cstr )
{
	if ( cstr )
		_yomikata.assign ( cstr );
}

inline void Parola::
set_gaikokugo ( const char *cstr )
{
	if ( cstr )
		_gaikokugo.assign ( cstr );
}

inline bool Parola::
has_kanji ( void ) const
{
	Glib::ustring::const_iterator _iter = _kotoba.begin();
	Glib::ustring::const_iterator _end = _kotoba.end();
	while ( _iter != _end )
	{
		if ( (*_iter >= 0x4E00 && *_iter <= 0x9FCF) || (*_iter >= 0x3400 && *_iter <= 0x4DBF) || (*_iter >= 0x20000 && *_iter <= 0x2A6DF) || (*_iter >= 0x2A700 && *_iter <= 0x2B73F) || (*_iter >= 0x2B740 && *_iter <= 0x2B81F) || (*_iter >= 0x2F800 && *_iter <= 0x2FA1F) || (*_iter >= 0xF900 && *_iter <= 0xFAFF) )
			return true;
		_iter++;
	}
	return false;
}

inline void Parola::
cleanup ( void )
{
	set_kotoba ( "" );
	set_yomikata ( "" );
	set_gaikokugo ( "" );
	set_tipo ( static_cast<char>( 0 ) );
	set_contesto ( "" );
	reset_stats ();
}

Glib::ustring Parola::
get_xml_string ( const Glib::ustring &language ) const
{
	Glib::ustring str;
	str.append ( Glib::ustring ( "<parola>\n" ) );
	str.append ( get_voce_xml () );
	str.append ( Glib::ustring ( "\t<kotoba>" + _kotoba + "</kotoba>\n" ) );
	str.append ( Glib::ustring ( "\t<yomikata>" + _yomikata + "</yomikata>\n" ) );
	str.append ( Glib::ustring ( "\t<gaikokugo lang=\"" + language + "\">" + _gaikokugo + "</gaikokugo>\n" ) );
	str.append ( Glib::ustring ( "\t<tipo>" + Glib::ustring::format ( static_cast<int>( _tipo ) ) + "</tipo>\n" ) );
	str.append ( Glib::ustring ( "</parola>\n" ) );
	return str;
}

#endif // _PAROLA_H_